package com.tanhua.server.service;

import cn.hutool.core.collection.CollUtil;
import com.alibaba.fastjson.JSON;
import com.tanhua.autoconfig.template.OssTemplate;
import com.tanhua.commons.utils.Constants;
import com.tanhua.dubbo.api.MovementApi;
import com.tanhua.dubbo.api.UserInfoApi;
import com.tanhua.dubbo.api.VisitorsApi;
import com.tanhua.model.domain.FreezeDetail;
import com.tanhua.model.domain.UserInfo;
import com.tanhua.model.mongo.Movement;
import com.tanhua.model.mongo.Visitors;
import com.tanhua.model.vo.ErrorResult;
import com.tanhua.model.vo.MovementsVo;
import com.tanhua.model.vo.PageResult;
import com.tanhua.model.vo.VisitorsVo;
import com.tanhua.server.exception.BusinessException;
import com.tanhua.server.interceptor.UserHolder;
import org.apache.dubbo.config.annotation.DubboReference;
import org.aspectj.weaver.ast.Var;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class MovementsService {

    @Autowired
    private OssTemplate ossTemplate;

    @DubboReference
    private MovementApi movementApi;

    @DubboReference
    private UserInfoApi userInfoApi;

    @Autowired
    private RedisTemplate<String,String> redisTemplate;

    @Autowired
    private MqMessageService mqMessageService;
    //构建Movement对象，调用API保存
    public void publishMovement(String textContent, MultipartFile[] imageContent) throws IOException {
        String redisKey = Constants.USER_FREEZE+"_"+UserHolder.getUserId().toString();
      //  String hashKey = Constants.FREEZE_USER+UserHolder.getUserId().toString();
        Boolean hasKey = redisTemplate.hasKey(redisKey);
        if(hasKey){
            String toString = redisTemplate.opsForValue().get(redisKey);

                FreezeDetail freeze = JSON.parseObject(toString, FreezeDetail.class);
                Integer freezingRange = freeze.getFreezingRange();
                if(freezingRange==3){
                    throw new BusinessException(ErrorResult.dongjie());

            }
        }

        //1、将图片上传到阿里云OSS
        List<String> medias = new ArrayList<>();
        for (MultipartFile multipartFile : imageContent) {
            String imageUrl = ossTemplate.upload(multipartFile.getOriginalFilename(),
                    multipartFile.getInputStream());
            medias.add(imageUrl);
        }
        //2、构造Movement对象
        Movement movement = new Movement();
        movement.setTextContent(textContent);
        movement.setMedias(medias);
        movement.setUserId(UserHolder.getUserId());
        movement.setCreated(System.currentTimeMillis());

        //3、调用API保存
        String movementId = movementApi.pushlish(movement);

        //4、发布审核消息：消息内容（动态ID）
        mqMessageService.sendAudiService(movementId);
    }

    //根据id，查询动态详情
    public PageResult findByUserId(Integer page, Integer pagesize, Long userId) {
        //1、根据用户id，查询此用户发布的动态详情列表（） List<Movement>
        List<Movement> list = movementApi.findByUserId(userId,page,pagesize);
        return initPage(list,page,pagesize);
    }

    //查询好友动态
    public PageResult findFriendMovements(Integer page, Integer pagesize) {
        //查询我的好友发布的动态详情列表  List<Movement>
        List<Movement> list = movementApi.findFriendMovements(UserHolder.getUserId(),page,pagesize);
        //根据动态中的用户id查询用户详情
        return initPage(list,page,pagesize);
    }

    private PageResult initPage(List<Movement> list,Integer page, Integer pagesize) {
        if(CollUtil.isEmpty(list)) {
            return new PageResult();
        }
        //2、根据动态中的用户id查询用户详情
        List<Long> userIds = CollUtil.getFieldValues(list, "userId", Long.class);
        Map<Long, UserInfo> map = userInfoApi.findByIds(userIds, null);
        //3、一个Movement构造一个MovementVo
        List<MovementsVo> vos = new ArrayList<>();
        for (Movement movement : list) {
            UserInfo userInfo = map.get(movement.getUserId());
            if (userInfo != null) {
                MovementsVo vo = MovementsVo.init(userInfo, movement); //是否点赞和是否喜欢全部都是默认值
                //判断当前用户对此动态是否已经点赞
                String redisKey = Constants.MOVEMENTS_INTERACT_KEY
                        + movement.getId().toHexString();

                String hashKey = Constants.MOVEMENT_LIKE_HASHKEY
                        + UserHolder.getUserId();
                Boolean hasKey = redisTemplate.opsForHash().hasKey(redisKey, hashKey);
                if(hasKey) {
                    vo.setHasLiked(1); //已点赞
                }
                vos.add(vo);
            }
        }
        //返回值
        return new PageResult(page,pagesize,0l,vos);
    }


    //查询推荐动态   5,5   20
    public PageResult findRecommendMovements(Integer page, Integer pagesize) {
        //1、拼接key从redis中查询推荐数据
        // key：MOVEMENTS_RECOMMEND_106
        // value：10020,22,17,10015,10099,23,10040,28,27,26,20,10093,21,10064,24,16,18,10081,19,10067（PID）
        String key = "MOVEMENTS_RECOMMEND_" + UserHolder.getUserId();
        String value = redisTemplate.opsForValue().get(key);
        //2、判断推荐数据是否存在，如果不存在，随机查询10条
        List<Movement> list = new ArrayList<>();

        if(StringUtils.isEmpty(value)) {
            list = movementApi.randomMovements(10); //随机获取指定条数的动态
        }else {
            //3、如果推荐的数据存在。对pid的字符串进行分页处理  List<Pid> : 10020,22,17,10015,10099
            String[] values = value.split(",");
            //判断，是否存在当前页的数据
            if ((page-1) * pagesize >= values.length) {
                return new PageResult();
            }
            List<Long> pids = Arrays.stream(values)
                    .skip((page - 1) * pagesize)
                    .limit(pagesize)
                    .map(e -> Long.valueOf(e))  //对数组中每个元素进行处理
                    .collect(Collectors.toList()); //获取list集合
            //4、根据pid的集合查询动态详情
            list = movementApi.findByPids(pids);
        }

        //5、返回值
        return initPage(list,page,pagesize);
    }


    //根据动态id查询动态详情
    public MovementsVo findMovementById(String id) {
        //1、根据动态id查询动态  Movement
        Movement movement = movementApi.findById(id);
        //2、构建movementVo对象
        Long userId = movement.getUserId();//当前动态发布人的id
        UserInfo userInfo = userInfoApi.findById(userId);

        mqMessageService.sendLogService(UserHolder.getUserId(),"0202","movement",id);
        return MovementsVo.init(userInfo,movement);
    }

    @DubboReference
    private VisitorsApi visitorsApi;

    //谁看过我
    public List<VisitorsVo> visitors() {
        //1、当前用户id
        Long userId = UserHolder.getUserId();
        //2、查询redis，获取当前用户查看访客列表的时间（毫秒数）
        String key = Constants.VISITORS_USER;
        String hashKey = userId.toString();
        String value = (String) redisTemplate.opsForHash().get(key,hashKey);
        //3、如果上次查看的时间不存在（默认值：0）
        Long date = StringUtils.isEmpty(value) ? 0l : Long.valueOf(value);

        //4、调用API查询访客数据（按照时间排序，查询前5条）  List<Visitors>
        List<Visitors> list = visitorsApi.queryMyVisitors(userId,date);
        //5、数据转化的过程
        List<Long> userIds = CollUtil.getFieldValues(list, "visitorUserId",
                Long.class);//访客的用户信息
        Map<Long, UserInfo> map = userInfoApi.findByIds(userIds, null);
        //构造返回值
        List<VisitorsVo> vos = new ArrayList<>();
        for (Visitors visitors : list) {
            //根据每个访客的id，获取每个访客详情
            UserInfo info = map.get(visitors.getVisitorUserId());
            if(info != null) {
                VisitorsVo vo = VisitorsVo.init(info, visitors);
                vos.add(vo);
            }
        }

        return vos;
    }
}
